﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace XPathAutoSuggest {
    /// <summary>
    /// The types of XML nodes we care about
    /// </summary>
    public enum XmlHelperNodeType {
        /// <summary>An XML tag that starts with &lt;/ </summary>
        ClosingTag,
        /// <summary>A normal XML tag that DOES NOT end with /&gt;, there is another node that closes it</summary>
        NormalWithClosingTag,
        /// <summary>An XML tag that ends with /&gt;</summary>
        NormalNoClosingTag,
        /// <summary>An XML node that contains data</summary>
        XmlData,
        /// <summary>An XML comment</summary>
        Comment,
        /// <summary>Special XML tag that starts with &lt;?</summary>
        Question
    }

    /// <summary>
    /// Suitable for holding/parsing an XML node with a Node Type, node name
    /// </summary>
    public class XmlHelperNode {
        string _EntireTag;
        string _NodeName;

        /// <summary>
        /// Such as ClosingTag or Comment
        /// </summary>
        public XmlHelperNodeType NodeType { get; set; }

        /// <summary>
        /// All the text from the opening angle bracket to the final close bracket
        /// </summary>
        public string EntireTag {
            get { return _EntireTag; }
            set { _EntireTag = value; }
        }

        /// <summary>
        /// The name of the node
        /// </summary>
        public string NodeName {
            get { return _NodeName; }
            set { _NodeName = value; }
        }

        /// <summary>
        /// Constructor builds the class using the raw text
        /// </summary>
        /// <param name="newNodeText">The text composing the node</param>
        /// <remarks>The main thing is this method determines what kind of node has
        /// been provided to us by the callser and sets the NodeType property accordingly</remarks>
        public XmlHelperNode(string newNodeText) {
            _EntireTag = newNodeText;
            if (newNodeText.StartsWith("<![CDATA[")) {
                NodeType = XmlHelperNodeType.XmlData;
                int p = newNodeText.LastIndexOf("]]>");
                _NodeName = newNodeText.Substring(9, p - 9);
            } else if (newNodeText.StartsWith("<?")) {
                NodeType = XmlHelperNodeType.Question;
                int p = newNodeText.IndexOf(" ", 2);
                _NodeName = newNodeText.Substring(2, p - 2);
            } else if (newNodeText.StartsWith("<!--")) {
                NodeType = XmlHelperNodeType.Comment;
                _NodeName = newNodeText.Substring(4, newNodeText.Length - 7);
            } else {
                if (newNodeText.EndsWith("/>")) {
                    NodeType = XmlHelperNodeType.NormalNoClosingTag;
                    int p = newNodeText.IndexOf(" ");
                    _NodeName = newNodeText.Substring(1, p - 1);
                } else if (newNodeText.StartsWith("</")) {
                    NodeType = XmlHelperNodeType.ClosingTag;
                    _NodeName = newNodeText.Substring(2, newNodeText.Length - 3);
                } else if (Regex.IsMatch(newNodeText, "^<[a-zA-Z].*[a-zA-Z]?>$")) {
                    NodeType = XmlHelperNodeType.NormalWithClosingTag;
                    int p = newNodeText.IndexOf(" ");
                    if (p > 0) {
                        _NodeName = newNodeText.Substring(1, p - 1);
                    } else {
                        _NodeName = newNodeText.Substring(1, newNodeText.Length - 2);
                    }
                }
            }
        }

        /// <summary>
        /// Displays the node name
        /// </summary>
        /// <returns>Node name</returns>
        public override string ToString() {
            return _NodeName;
        }
    }
}
